/**
 * author: Robert Scheller
 * created: 06. 11. 20009
 * modified: 10. 11. 2009
 *
 * HLSL Convolution Filter with variable kernel.
 */

int width;
int height;
int edge_lenght; // Kantenlaenge des Kernels
float divisor;
float bias;
texture image_texture;
texture kernel;

sampler2D image_map = sampler_state
{
  Texture = (image_texture);
};
sampler2D kernel_map = sampler_state
{
  Texture = (kernel);
};

float4 PixelShaderMain(float2 texture_coordinate : TEXCOORD0) : COLOR0
{
  float2 delta_texture = float2(1.0f / width, 1.0f / height);
  float2 delta_kernel  = float2(1.0f / edge_lenght, 1.0f / edge_lenght);
  int radius = edge_lenght / 2;
  
  float4 value = float4(.0f, .0f, .0f, .0f);

  for (int y = 0; y < edge_lenght; y++)
    for (int x = 0; x < edge_lenght; x++)
    {
      float2 position_texture = float2(x - radius, radius - y) * delta_texture;
      float2 position_kernel  = float2(x, y) * delta_kernel;
      float kernel_factor = tex2D(kernel_map, position_kernel).r * 255;
    
      if(tex2D(kernel_map, position_kernel).g != 0.0f)
        kernel_factor = -kernel_factor;
      value += tex2D( image_map, texture_coordinate + position_texture ) * kernel_factor;
    }

  value.r = min(max(value.r/divisor + bias, 0), 1);
  value.g = min(max(value.g/divisor + bias, 0), 1);
  value.b = min(max(value.b/divisor + bias, 0), 1);
  return value;
}

technique Convolution
{
  pass Pass_0
  {
    PixelShader = compile ps_3_0 PixelShaderMain();
  }
}